using Cysharp.Threading.Tasks;
using DTT.AreaOfEffectRegions;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.Logic;
using LFloatMath.Math;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class ChargeViewComponent : TComponent
    {
        public UnitView unit;
        private BattleSceneEntityView indicator;
        private bool showIndicator;
        private TargetSelectConfig curChargeSelect;
        private uint collisionID;

        private BattleRenderCollisionController collisionCtrl => BattleManager.Instance.ctrl.collisionCtrl;

        protected override void OnDispose()
        {
        }

        public override void OnCreate(TEntity entity)
        {
            this.unit = (UnitView)entity;
        }

        public async UniTaskVoid StartCharge(string rIndicatorName, TargetSelectConfig rTargetConfig, Vector3 rPos, Vector3 rAspect)
        {
            this.showIndicator = true;
            this.curChargeSelect = rTargetConfig;
            this.indicator = await LoadIndicator(rIndicatorName, rTargetConfig);
            if (!this.showIndicator)
            {
                this.FreeIndicator();
                return;
            }
            if (this.indicator != null)
            {
                var rTrans = this.indicator.transform;
                rTrans.rotation = Quaternion.LookRotation(rAspect);
                rTrans.localPosition = rPos;

                this.collisionCtrl.CreateIndicatorCollision(this.unit, rTargetConfig, rPos, rAspect, this.indicator, this.CheckCollision, ref this.collisionID);
            }
            var rAnimComp = this.unit.GetComponent<BattleAnimationComponent>(ETComponentType.BattleAnimationComponent);
            rAnimComp.SetCharge(true);
        }

        public void ChargeStop()
        {
            this.showIndicator = false;
            var rAnimComp = this.unit.GetComponent<BattleAnimationComponent>(ETComponentType.BattleAnimationComponent);
            rAnimComp.SetCharge(false);
            this.FreeIndicator();
            BattleManager.Instance.ctrl.collisionCtrl.RemoveTempCollision(this.collisionID);
            this.collisionID = 0;
            this.curChargeSelect = null;
        }

        private void FreeIndicator()
        {
            if (this.indicator != null)
            {
                this.indicator.Put();
                this.indicator = null;
            }
        }

        private async UniTask<BattleSceneEntityView> LoadIndicator(string indicatorName, TargetSelectConfig rTargetConfig)
        {
            var rIndicator = ManagerCenter.Entity.Get(PathConstant.GetSkillSelectPath(indicatorName),
                (int)EntityPoolGroupType.BattleSceneEntity) as BattleSceneEntityView;
            if (rIndicator == null)
            {
                return null;
            }
            await rIndicator.Load();
            rIndicator.transform.SetParent(BattleManager.Instance.ctrl.sceneCtrl.targetSelect);
            switch ((ETargetSelectType)rTargetConfig.type)
            {
                case ETargetSelectType.Circle:
                {
                    var rRegion = rIndicator.gameObject.GetComponent<CircleRegion>();
                    rIndicator.comp = rRegion;
                    if (rTargetConfig.customConfig is TargetSelect_Circle_ConfigData rConfig)
                    {
                        rRegion.Radius = new LFloat(true, rConfig.raduis).ToFloat();
                    }
                    break;
                }
                case ETargetSelectType.Fan:
                {
                    var rRegion = rIndicator.gameObject.GetComponent<ArcRegion>();
                    rIndicator.comp = rRegion;
                    if (rTargetConfig.customConfig is TargetSelect_Fan_ConfigData rConfig)
                    {
                        rRegion.Radius = new LFloat(true, rConfig.raduis).ToFloat();
                        rRegion.Arc = new LFloat(true, rConfig.angle).ToFloat();
                    }
                    break;
                }
                case ETargetSelectType.Cub:
                {
                    var rRegion = rIndicator.gameObject.GetComponent<LineRegion>();
                    rIndicator.comp = rRegion;
                    if (rTargetConfig.customConfig is TargetSelect_Cub_ConfigData rConfig)
                    {
                        rRegion.Width = new LFloat(true, rConfig.width).ToFloat();
                        rRegion.Length = new LFloat(true, rConfig.length).ToFloat();
                    }
                    break;
                }
            }
            return rIndicator;
        }

        private bool CheckCollision(CollisionViewComponent comp)
        {
            var rSelect = this.curChargeSelect;
            if (rSelect != null)
            {
                // 表现层队伍判断无法判断自身，需要分开
                if (this.unit != comp.unit)
                {
                    var rRelation = BattleUtil.CheckTeamRelation(this.unit.teamIndex, comp.unit.teamIndex);
                    return (rSelect.targetRelation & (int)rRelation) > 0;
                }
                else
                {
                    return (rSelect.targetRelation & (int)ETargetRelation.Self) > 0;
                }
            }
            return false;
        }
    }
}